
#include <cstdio>
#include "delegate.h"
#include "bind.h"


void void_foo0()
{
	printf("void void_foo0()\n");
}

int int_foo0()
{
	printf("int int_foo0()\n");
	return 0;
}


void void_foo1(int)
{
	printf("void void_foo1(int)\n");
}

int int_foo1(int)
{
	printf("int int_foo1(int)\n");
	return 0;
}

void void_foo2(int a, int b)
{
	printf("void void_foo2(%d,%d)\n",a,b);
}

int int_foo2(int a, int b)
{
	printf("int int_foo2(%d,%d)\n",a,b);
	return 0;
}

void void_foo3(int,int,int)
{
	printf("void void_foo3(int,int,int)\n");
}

int int_foo3(int,int,int)
{
	printf("int int_foo3(int,int,int)\n");
	return 0;
}

void void_foo4(int,int,int,int)
{
	printf("void void_foo4(int,int,int,int)\n");
}

int int_foo4(int,int,int,int)
{
	printf("int int_foo4(int,int,int,int)\n");
	return 0;
}

void void_foo5(int,int,int,int,int)
{
	printf("void void_foo5(int,int,int,int,int)\n");
}

int int_foo5(int,int,int,int,int)
{
	printf("int int_foo5(int,int,int,int,int)\n");
	return 0;
}

void void_foo6(int,int,int,int,int,int)
{
	printf("void void_foo6(int,int,int,int,int,int)\n");
}

int int_foo6(int,int,int,int,int,int)
{
	printf("int int_foo6(int,int,int,int,int,int)\n");
	return 0;
}

void void_foo7(int,int,int,int,int,int,int)
{
	printf("void void_foo7(int,int,int,int,int,int,int)\n");
}

int int_foo7(int,int,int,int,int,int,int)
{
	printf("int int_foo7(int,int,int,int,int,int,int)\n");
	return 0;
}

void void_foo8(int,int,int,int,int,int,int,int)
{
	printf("void void_foo8(int,int,int,int,int,int,int,int)\n");
}

int int_foo8(int,int,int,int,int,int,int,int)
{
	printf("int int_foo8(int,int,int,int,int,int,int,int)\n");
	return 0;
}

class Foo
{
public:
	void m_void_foo0()
	{
		printf("void m_void_foo0()\n");
	}

	int m_int_foo0()
	{
		printf("int m_int_foo0()\n");
		return 0;
	}


	void m_void_foo1(int)
	{
		printf("void m_void_foo1(int)\n");
	}

	int m_int_foo1(int)
	{
		printf("int m_int_foo1(int)\n");
		return 0;
	}

	void m_void_foo2(int,int)
	{
		printf("void m_void_foo2(int,int)\n");
	}

	int m_int_foo2(int,int)
	{
		printf("int m_int_foo2(int,int)\n");
		return 0;
	}

	void m_void_foo3(int,int,int)
	{
		printf("void m_void_foo3(int,int,int)\n");
	}

	int m_int_foo3(int,int,int)
	{
		printf("int m_int_foo3(int,int,int)\n");
		return 0;
	}

	void m_void_foo4(int,int,int,int)
	{
		printf("void m_void_foo4(int,int,int,int)\n");
	}

	int m_int_foo4(int,int,int,int)
	{
		printf("int m_int_foo4(int,int,int,int)\n");
		return 0;
	}

	void m_void_foo5(int,int,int,int,int)
	{
		printf("void m_void_foo5(int,int,int,int,int)\n");
	}

	int m_int_foo5(int,int,int,int,int)
	{
		printf("int m_int_foo5(int,int,int,int,int)\n");
		return 0;
	}

	void m_void_foo6(int,int,int,int,int,int)
	{
		printf("void m_void_foo6(int,int,int,int,int,int)\n");
	}

	int m_int_foo6(int,int,int,int,int,int)
	{
		printf("int m_int_foo6(int,int,int,int,int,int)\n");
		return 0;
	}

	void m_void_foo7(int,int,int,int,int,int,int)
	{
		printf("void m_void_foo7(int,int,int,int,int,int,int)\n");
	}

	int m_int_foo7(int,int,int,int,int,int,int)
	{
		printf("int m_int_foo7(int,int,int,int,int,int,int)\n");
		return 0;
	}

	void m_void_foo8(int,int,int,int,int,int,int,int)
	{
		printf("void m_void_foo8(int,int,int,int,int,int,int,int)\n");
	}

	int m_int_foo8(int,int,int,int,int,int,int,int)
	{
		printf("int m_int_foo8(int,int,int,int,int,int,int,int)\n");
		return 0;
	}
};

int main()
{
	int ret = 0;
	bind<void>(void_foo0)();
	ret = bind<int>(int_foo0)();

	bind<void>(void_foo1,1)();
	bind<void>(void_foo1,_1)(1);
	ret = bind<int>(int_foo1,1)();
	ret = bind<int>(int_foo1,_1)(1);

	bind<void>(void_foo2,1,2)();
	bind<void>(void_foo2,_1,2)(1);
	bind<void>(void_foo2,_1,_2)(1,2);
	bind<void>(void_foo2,_2,_1)(2,1);
	ret = bind<int>(int_foo2,1,2)();
	ret = bind<int>(int_foo2,_1,2)(1);
	ret = bind<int>(int_foo2,_1,_2)(1,2);
	ret = bind<int>(int_foo2,_2,_1)(2,1);


	bind<void>(void_foo3,1,2,3)();
	bind<void>(void_foo3,_1,2,3)(1);
	bind<void>(void_foo3,_1,_2,3)(1,2);
	bind<void>(void_foo3,_1,_2,_3)(1,2,3);
	ret = bind<int>(int_foo3,_1,_2,_3)(1,2,3);
	ret = bind<int>(int_foo3,_1,_2,3)(1,2);
	ret = bind<int>(int_foo3,_2,_1,_3)(2,1,3);
	
	bind<void>(void_foo4,1,2,3,4)();
	bind<void>(void_foo4,_1,2,3,4)(1);
	bind<void>(void_foo4,_1,_2,3,4)(1,2);
	bind<void>(void_foo4,_1,_2,_3,4)(1,2,3);
	bind<void>(void_foo4,_1,_2,_3,_4)(1,2,3,4);
	ret = bind<int>(int_foo4,_1,_2,_3,_4)(1,2,3,4);
	ret = bind<int>(int_foo4,_1,_2,_3,4)(1,2,3);
	ret = bind<int>(int_foo4,_2,_1,_3,_4)(2,1,3,4);
	
	bind<void>(void_foo5,1,2,3,4,5)();
	bind<void>(void_foo5,_1,2,3,4,5)(1);
	bind<void>(void_foo5,_1,_2,3,4,5)(1,2);
	bind<void>(void_foo5,_1,_2,_3,4,5)(1,2,3);
	bind<void>(void_foo5,_1,_2,_3,_4,5)(1,2,3,4);
	bind<void>(void_foo5,_1,_2,_3,_4,_5)(1,2,3,4,5);
	bind<void>(void_foo5,_1,_2,_3,_4,_5)(1,2,3,4,5);	
	ret = bind<int>(int_foo5,_1,_2,_3,_4,_5)(1,2,3,4,5);
	ret = bind<int>(int_foo5,_1,_2,_3,_4,5)(1,2,3,4);
	ret = bind<int>(int_foo5,_2,_1,_3,_4,_5)(2,1,3,4,5);
	
	bind<void>(void_foo6,1,2,3,4,5,6)();
	bind<void>(void_foo6,_1,2,3,4,5,6)(1);
	bind<void>(void_foo6,_1,_2,3,4,5,6)(1,2);
	bind<void>(void_foo6,_1,_2,_3,4,5,6)(1,2,3);
	bind<void>(void_foo6,_1,_2,_3,_4,5,6)(1,2,3,4);
	bind<void>(void_foo6,_1,_2,_3,_4,_5,6)(1,2,3,4,5);
	bind<void>(void_foo6,_1,_2,_3,_4,_5,_6)(1,2,3,4,5,6);	
	ret = bind<int>(int_foo6,_1,_2,_3,_4,_5,_6)(1,2,3,4,5,6);
	ret = bind<int>(int_foo6,_1,_2,_3,_4,_5,6)(1,2,3,4,5);
	ret = bind<int>(int_foo6,_2,_1,_3,_4,_5,_6)(2,1,3,4,5,6);
	
	bind<void>(void_foo7,1,2,3,4,5,6,7)();
	bind<void>(void_foo7,_1,2,3,4,5,6,7)(1);
	bind<void>(void_foo7,_1,_2,3,4,5,6,7)(1,2);
	bind<void>(void_foo7,_1,_2,_3,4,5,6,7)(1,2,3);
	bind<void>(void_foo7,_1,_2,_3,_4,5,6,7)(1,2,3,4);
	bind<void>(void_foo7,_1,_2,_3,_4,_5,6,7)(1,2,3,4,5);
	bind<void>(void_foo7,_1,_2,_3,_4,_5,_6,7)(1,2,3,4,5,6);	
	ret = bind<int>(int_foo7,_1,_2,_3,_4,_5,_6,7)(1,2,3,4,5,6);
	ret = bind<int>(int_foo7,_1,_2,_3,_4,_5,_6,_7)(1,2,3,4,5,6,7);
	ret = bind<int>(int_foo7,_2,_1,_3,_4,_5,_6,7)(2,1,3,4,5,6);
	
	
	bind<void>(void_foo8,_1,2,3,4,5,6,7,8)(1);
	bind<void>(void_foo8,_1,_2,3,4,5,6,7,8)(1,2);
	bind<void>(void_foo8,_1,_2,_3,4,5,6,7,8)(1,2,3);
	bind<void>(void_foo8,_1,_2,_3,_4,5,6,7,8)(1,2,3,4);
	bind<void>(void_foo8,_1,_2,_3,_4,_5,6,7,8)(1,2,3,4,5);
	bind<void>(void_foo8,_1,_2,_3,_4,_5,_6,7,8)(1,2,3,4,5,6);	
	ret = bind<int>(int_foo8,_1,_2,_3,_4,_5,_6,7,8)(1,2,3,4,5,6);
	ret = bind<int>(int_foo8,_1,_2,_3,_4,_5,_6,7,8)(1,2,3,4,5,6);
	ret = bind<int>(int_foo8,_1,_2,_3,_4,_5,_6,7,8)(1,2,3,4,5,6);
	ret = bind<int>(int_foo8,_1,_2,_3,_4,_5,_6,7,8)(1,2,3,4,5,6);
	ret = bind<int>(int_foo8,_1,_2,_3,_4,_5,_6,7,8)(1,2,3,4,5,6);
	

	Foo f;
	delegate::Delegate<int (int,int)> d_int_foo2;
	d_int_foo2 = bind<int>(std::make_pair(&f,&Foo::m_int_foo3),_1,_2,3);
	d_int_foo2(1,2);


	return 0;
}
